﻿HmJS.$Import('core.core');

/*
---
version: 0.3-4
description: Simulating process threading in a javascript loop, using MooTools.
license: MIT-style
download: http://mootools.net/forge/p/threaded_loop
source: http://github.com/sixtyseconds/mootools-threaded-loop

authors: [Christopher Pitt]

provides: [ThreadedLoop]
requires: 
core/1.3: [Class.Extras, Number, Array]
...
*/

HmJS.register('lang.ThreadedLoop', function ($ns) {

	var ThreadedLoop = new Class({

		'Implements': [Events, Options],

		'options': {
			/*
			'onInitialize': $empty,
			'onStart': $empty,
			'onStop': $empty,
			'onPause': $empty,
			'onResume': $empty,
			'onProcess': $empty,
			'onComplete': $empty,
			*/
			'chunk': 10,
			'interval': 1
		},

		'initialize': function (source, options) {
			this.setOptions(options);

			if (typeOf(source) == 'number') {
				this.type = 'number';
				this.limit = source;
			} else if (typeOf(source) == 'array') {
				this.type = 'array';
				this.array = source;
				this.limit = source.length;
			} else {
				throw ('Source is not of type Number or Array!');
			}

			this.index = 0;
			this.fireEvent('onInitialize', [this.index]);
		},

		'stop': function () {
			clearInterval(this.$interval);
			this.index = 0;
			this.fireEvent('onStop', [this.index]);
		},

		'start': function (index) {
			this.index = index || 0;
			this.$interval = setInterval(this.process.bind(this), this.options.interval);
			this.fireEvent('onStart', [index]);
		},

		'pause': function () {
			clearInterval(this.$interval);
			this.fireEvent('onPause', [this.index]);
		},

		'resume': function () {
			this.start(this.index);
			this.fireEvent('onResume', [this.index]);
		},

		'process': function () {
			var limit = this.limit,
					chunk = this.index + this.options.chunk;

			if (this.type == 'number') {
				while ((this.index < chunk) && (this.index < limit)) {
					this.fireEvent('onProcess', [this.index]);
					this.index++;
				}
			} else {
				while ((this.index < chunk) && (this.index < limit)) {
					this.fireEvent('onProcess', [this.array[this.index], this.index]);
					this.index++;
				}
			}

			if (this.index == this.limit) {
				this.stop();
				this.fireEvent('onComplete', [this.limit]);
			}
		}

	});

	Array.implement({
		'loop': function (options) {
			new ThreadedLoop(this, options).start();
			return this;
		}
	});

	if (typeof exports != 'undefined') {
		exports.ThreadedLoop = ThreadedLoop;
	}
	if (typeof window != 'undefined') {
		window.ThreadedLoop = ThreadedLoop;
	}

	return ThreadedLoop;
});